package controller

import (
	"encoding/json"
	"gdfs-center/controller/ao"
	"gdfs-center/controller/vo"
	"gdfs-center/db"
	"gdfs-center/engine"
	"gdfs-center/err"
	"gdfs-center/logcat"
	"gdfs-center/socket/cmdGenerate"
	"gdfs-center/socket/codec"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"log"
)

func equalStoreIp(ip string) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		return db.Where("store_ip = ?", ip)
	}
}

func likeStoreId(id string) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		return db.Where("store_id like ?", "%"+id+"%")
	}
}

//查询存储服务列表
func GetStorelistOption(c *gin.Context) {
	c.Writer.Header().Set("content-type", "application/json")
	var optionVos []vo.StoreOptionVo
	stores := engine.GetEngine().StoreMap
	for _, s := range stores {
		var optionVo vo.StoreOptionVo
		optionVo.StoreIp = s.Ip
		optionVo.StoreId = s.StoreID
		optionVos = append(optionVos, optionVo)
	}
	WritedString(c.Writer, true, "0", "处理成功", optionVos)
}

//查询文件服务系统信息
func GetStoreSystemInfo(c *gin.Context) {
	c.Writer.Header().Set("content-type", "application/json")
	var svo vo.StoreSystemInfoVo
	var sao ao.GetStoreInfoAo
	jsonerr := json.Unmarshal(GetPostJson(c.Request), &sao)
	if jsonerr != nil {
		logcat.GetLog().Sugar().Info("###jsonerr:", jsonerr)
		WritedString(c.Writer, false, err.JSONERR, err.Errortype[err.JSONERR], svo)
		return
	}
	var sinfo db.SystemInfo
	db.GetDB().Where("store_id = ?", sao.StoreId).First(&sinfo)
	svo.CpuGhz = sinfo.CpuGhz
	svo.CpuPercent = sinfo.CpuPercent
	svo.CpuCount = sinfo.CpuCount
	svo.MemUsed = sinfo.MemUsed
	svo.MemTotal = sinfo.MemTotal
	svo.MemPercent = sinfo.MemPercent
	svo.DiskTotal = sinfo.DiskTotal
	svo.DiskPercent = sinfo.DiskPercent
	svo.DiskUsed = sinfo.DiskUsed
	svo.SwapUsed = sinfo.SwapUsed
	svo.SwapPercent = sinfo.SwapPercent
	svo.SwapTotal = sinfo.SwapTotal
	WritedString(c.Writer, true, "0", "处理成功", svo)
}

//分页查询服务列表
func GetStoreList(c *gin.Context) {
	c.Writer.Header().Set("content-type", "application/json")
	//解析入参
	var storelistao ao.StoreListAo
	var pageresult vo.PageResult
	//logcat.GetLog().Sugar().Info("#########请求json:",string(GetPostJson(c.Request)))
	jsonerr := json.Unmarshal(GetPostJson(c.Request), &storelistao)
	if jsonerr != nil {
		logcat.GetLog().Sugar().Info("###jsonerr:", jsonerr)
		WritedString(c.Writer, false, err.JSONERR, err.Errortype[err.JSONERR], pageresult)
		return
	}
	log.Println("##StoreIp", storelistao.StoreIp, "###storeid", storelistao.StoreId)
	//校验参数
	if storelistao.PageNum == 0 {
		WritedString(c.Writer, false, err.NOTVALID_ERROR, err.Errortype[err.NOTVALID_ERROR], pageresult)
		return
	}
	if storelistao.PageSize == 0 {
		WritedString(c.Writer, false, err.NOTVALID_ERROR, err.Errortype[err.NOTVALID_ERROR], pageresult)
		return
	}
	var scopes []func(*gorm.DB) *gorm.DB
	if storelistao.StoreIp != "" {
		log.Println("###storelistao.StoreIp != nil")
		scopes = append(scopes, equalStoreIp(storelistao.StoreIp))
	}
	if storelistao.StoreId != "" {
		log.Println("###storelistao.StoreId != nil")
		scopes = append(scopes, likeStoreId(storelistao.StoreId))
	}
	var total int64
	var stores []db.Store
	var storelistvo []vo.StorelistVo
	db.GetPageQueryTotal(scopes).Find(&stores).Count(&total)
	db.PageQuery(scopes, storelistao.PageSize, storelistao.PageNum, "created_at desc").Find(&stores)
	for _, s := range stores {
		var svo vo.StorelistVo
		svo.HttpPort = s.HttpPort
		svo.StoreId = s.StoreId
		svo.StoreIp = s.StoreIp
		var n db.Node
		db.GetDB().Where("node_id = ?", s.NodeId).First(&n)
		svo.NodeName = n.NodeName
		if _, ok := engine.GetEngine().StoreMap[s.StoreId]; ok {
			online := engine.GetEngine().StoreMap[s.StoreId].IsAlive()
			logcat.GetLog().Sugar().Info("###是否在线storeid:", s.StoreId, "//online:", online)
			if online {
				svo.Status = "在线" //在线
			} else {
				svo.Status = "离线" //离线
			}
		} else {
			svo.Status = "离线" //离线
		}
		var heartbeat db.HeartBeat
		db.GetDB().Where("store_id = ?", s.StoreId).First(&heartbeat)
		if heartbeat == (db.HeartBeat{}) {
			svo.HeartTime = ""
		} else {
			svo.HeartTime = heartbeat.UpdatedAt.Local().Format("2006-01-02 15:04:05")
		}
		storelistvo = append(storelistvo, svo)
	}
	pageresult.PageNum = storelistao.PageNum
	pageresult.PageSize = storelistao.PageSize
	pageresult.Pages = int(total) / storelistao.PageSize
	pageresult.Total = total
	pageresult.List = storelistvo
	WritedString(c.Writer, true, "0", "处理成功", pageresult)
}

//存储服务解绑节点
func UnBindNode(c *gin.Context) {
	c.Writer.Header().Set("content-type", "application/json")
	var ao ao.UnbindNodeAo
	jsonerr := json.Unmarshal(GetPostJson(c.Request), &ao)
	if jsonerr != nil {
		logcat.GetLog().Sugar().Info("###jsonerr:", jsonerr)
		WritedString(c.Writer, false, err.JSONERR, err.Errortype[err.JSONERR], nil)
		return
	}
	if ao.StoreId == "" {
		WritedString(c.Writer, false, err.NOTVALID_ERROR, err.Errortype[err.NOTVALID_ERROR], nil)
		return
	}
	var store db.Store
	db.GetDB().Where("store_id = ?", ao.StoreId).First(&store)
	if store == (db.Store{}) {
		WritedString(c.Writer, false, err.SYSTEMERR, err.Errortype[err.SYSTEMERR], nil)
		return
	}
	engine.UnBindNode(store.StoreId)
	store.NodeId = ""
	db.GetDB().Save(&store)
	if _, ok := engine.GetEngine().StoreMap[ao.StoreId]; ok {
		s := engine.GetEngine().StoreMap[ao.StoreId]
		if s.IsAlive() {
			var nstores codec.NoticeNodeCmd
			nstores.NoticeStores = nil
			nstores.NodeID = ""
			s.Conn.Write(cmdGenerate.GenerateNotisNode(nstores))
		}
	}
	WritedString(c.Writer, true, err.SUCESS, err.Errortype[err.SUCESS], nil)
}

//删除存储服务(mysql和内存)
func RemoveStore(c *gin.Context) {
	c.Writer.Header().Set("content-type", "application/json")
	var removeao ao.StoreRemoveAo
	jsonerr := json.Unmarshal(GetPostJson(c.Request), &removeao)
	if jsonerr != nil {
		logcat.GetLog().Sugar().Info("###jsonerr:", jsonerr)
		WritedString(c.Writer, false, err.JSONERR, err.Errortype[err.JSONERR], nil)
		return
	}
	if removeao.StoreId == "" {
		WritedString(c.Writer, false, err.NOTVALID_ERROR, err.Errortype[err.NOTVALID_ERROR], nil)
		return
	}
	var store db.Store
	db.GetDB().Where("store_id =?", removeao.StoreId).First(&store)
	if store == (db.Store{}) {
		WritedString(c.Writer, false, err.NODBERR, err.Errortype[err.NODBERR], nil)
		return
	}
	db.GetDB().Delete(&store)
	if _, ok := engine.GetEngine().StoreMap[removeao.StoreId]; ok {
		stores := engine.GetEngine().StoreMap
		delete(stores, removeao.StoreId)
		var rstorevo vo.RemoveStoreVo
		rstorevo.StoreId = store.StoreId
		WritedString(c.Writer, true, err.SUCESS, err.Errortype[err.SUCESS], rstorevo)
		return
	}
	WritedString(c.Writer, false, err.DeleteErr, err.Errortype[err.DeleteErr], nil)
}

func FindStoreByNodeId(c *gin.Context) {
	c.Writer.Header().Set("content-type", "application/json")
	var f ao.FindStoreByNodeIdAo
	jsonerr := json.Unmarshal(GetPostJson(c.Request), &f)
	if jsonerr != nil {
		logcat.GetLog().Sugar().Info("###jsonerr:", jsonerr)
		WritedString(c.Writer, false, err.JSONERR, err.Errortype[err.JSONERR], nil)
		return
	}
	var stores []db.Store
	db.GetDB().Where("node_id = ?", f.NodeId).Find(&stores)
	if len(stores) == 0 {
		WritedString(c.Writer, false, err.FINDDBERR, err.Errortype[err.FINDDBERR], nil)
		return
	}
	var findvo vo.FindStoreByNodeIdVo
	for _, s := range stores {
		findvo.StoreIds = append(findvo.StoreIds, s.StoreId)
	}
	WritedString(c.Writer, true, err.SUCESS, err.Errortype[err.SUCESS], findvo)
}
